package cn.jeeweb.core.common.service.impl;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ff.common.util.format.DateUtil;
import com.ff.common.util.meta.ReflectionUtil;
import com.ff.common.util.validate.ValidatorUtil;

import cn.jeeweb.core.common.data.DuplicateValid;
import cn.jeeweb.core.common.service.ICommonService;
import cn.jeeweb.core.query.data.Page;
import cn.jeeweb.core.query.data.PageImpl;
import cn.jeeweb.core.query.data.Pageable;
import cn.jeeweb.core.query.data.Queryable;
import cn.jeeweb.core.query.parse.QueryToWrapper;
import cn.jeeweb.core.query.wrapper.EntityWrapper;
import cn.jeeweb.modules.sys.entity.User;
import cn.jeeweb.modules.sys.utils.UserUtils;

@Transactional
public class CommonServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements ICommonService<T> {

	@Override
	public Page<T> list(Queryable queryable) {
		EntityWrapper<T> entityWrapper = new EntityWrapper<T>();
		return list(queryable, entityWrapper);
	}

	@Override
	public Page<T> list(Queryable queryable, Wrapper<T> wrapper) {
		QueryToWrapper<T> queryToWrapper = new QueryToWrapper<T>();
		queryToWrapper.parseCondition(wrapper, queryable);
		// 排序问题
		queryToWrapper.parseSort(wrapper, queryable);
		Pageable pageable = queryable.getPageable();
		com.baomidou.mybatisplus.plugins.Page<T> page = new com.baomidou.mybatisplus.plugins.Page<T>(
				pageable.getPageNumber(), pageable.getPageSize());
		com.baomidou.mybatisplus.plugins.Page<T> content = selectPage(page, wrapper);
		return new PageImpl<T>(content.getRecords(), queryable.getPageable(), content.getTotal());
	}

	@Override
	public List<T> listWithNoPage(Queryable queryable) {
		EntityWrapper<T> entityWrapper = new EntityWrapper<T>();
		return listWithNoPage(queryable, entityWrapper);
	}

    public T selectOne(String field,Object value) {
    	Map<String,Object> filter = new HashMap<String,Object>();
    	List<T> data = super.selectByMap(filter);
    	if(null == data || data.isEmpty())
    	{
    		return null;
    	}
        return data.get(0);
    }
    public T selectOne(Map<String,Object> filter) {
     	List<T> data = super.selectByMap(filter);
    	if(null == data || data.isEmpty())
    	{
    		return null;
    	}
        return data.get(0);
    }
    
	@Override
	public T get(Queryable queryable) {
		EntityWrapper<T> entityWrapper = new EntityWrapper<T>();
		List<T> list = listWithNoPage(queryable, entityWrapper);
		if(null == list || list.isEmpty())
		{
			return null;
		}
		return list.get(0);
	}
	
	@Override
	public List<T> listWithNoPage(Queryable queryable, Wrapper<T> wrapper) {
		QueryToWrapper<T> queryToWrapper = new QueryToWrapper<T>();

		queryToWrapper.parseCondition(wrapper, queryable);
		// 排序问题
		queryToWrapper.parseSort(wrapper, queryable);
		List<T> content = selectList(wrapper);
		return content;
	}

	@Override
	public Boolean doValid(DuplicateValid duplicateValid, Wrapper<T> wrapper) {
		Boolean valid = Boolean.FALSE;
		String queryType = duplicateValid.getQueryType();
		if (StringUtils.isEmpty(queryType)) {
			queryType = "table";
		}
		if (queryType.equals("table")) {
			valid = validTable(duplicateValid, wrapper);
		}
		return valid;
	}

	private Boolean validTable(DuplicateValid duplicateValid, Wrapper<T> wrapper) {
		Integer num = null;
		String extendName = duplicateValid.getExtendName();
		String extendParam = duplicateValid.getExtendParam();
		if (!StringUtils.isEmpty(extendParam)) {
			// [2].编辑页面校验
			wrapper.eq(duplicateValid.getName(), duplicateValid.getParam()).ne(extendName, extendParam);
			num = baseMapper.selectCount(wrapper);
		} else {
			// [1].添加页面校验
			wrapper.eq(duplicateValid.getName(), duplicateValid.getParam());
			num = baseMapper.selectCount(wrapper);
		}

		if (num == null || num == 0) {
			// 该值可用
			return true;
		} else {
			// 该值不可用
			return false;
		}
	}

	@Override
	public boolean insert(T entity) {
		// TODO Auto-generated method stub
		ReflectionUtil.setObjectField(entity, "createDate", DateUtil.getCurrentDate());
 		 
		User user = UserUtils.getUser();
		if(null != user)
		{
		  Field field = ReflectionUtil.getFieldByName(entity.getClass(), "createBy");
		  if(null != field)
		  {
			  if(field.getType() == String.class)
			  {
				  ReflectionUtil.setObjectField(entity, "createBy", user.getId());
			  }
			  else
			  {
				  ReflectionUtil.setObjectField(entity, "createBy", user);
			  }
 		  }
 		}
		if(null != user)
		{
		  ReflectionUtil.setObjectField(entity, "createByName", user.getRealname());
 		}

		
		ReflectionUtil.setObjectField(entity, "modifyDate", DateUtil.getCurrentDate());
 		 
		return super.insert(entity);
	}
	
	

	@Override
	public boolean insertBatch(List<T> entityList) {
		// TODO Auto-generated method stub
		if(ValidatorUtil.isEmpty(entityList))
		{
			return true;
		}
		for(T e :entityList)
		{
			ReflectionUtil.setObjectField(e, "createDate", DateUtil.getCurrentDate());
	 		 
			User user = UserUtils.getUser();
			if(null != user)
			{
				Field field = ReflectionUtil.getFieldByName(e.getClass(), "createBy");
				  if(null != field)
				  {
					  if(field.getType() == String.class)
					  {
						  ReflectionUtil.setObjectField(e, "createBy", user.getId());
					  }
					  else
					  {
						  ReflectionUtil.setObjectField(e, "createBy", user);
					  }
		 		  }
	 		}
			if(null != user)
			{
			  ReflectionUtil.setObjectField(e, "createByName", user.getRealname());
	 		}

			
			ReflectionUtil.setObjectField(e, "updateDate", DateUtil.getCurrentDate());
	 		 
		}
		return super.insertBatch(entityList);
	}

	@Override
	public boolean insertOrUpdate(T entity) {
		// TODO Auto-generated method stub
		User user = UserUtils.getUser();
		if(null != user)
		{
			Field field = ReflectionUtil.getFieldByName(entity.getClass(), "updateBy");
		    if(null != field)
			  {
				  if(field.getType() == String.class)
				  {
					  ReflectionUtil.setObjectField(entity, "updateBy", user.getId());
				  }
				  else
				  {
					  ReflectionUtil.setObjectField(entity, "updateBy", user);
				  }
	 		  }
  		}
		if(null != user)
		{
		  ReflectionUtil.setObjectField(entity, "updateByName", user.getUsername());
 		}
		
		ReflectionUtil.setObjectField(entity, "updateDate", DateUtil.getCurrentDate());
		return super.insertOrUpdate(entity);
	}
	
	

}